/**
 * FormFieldImgs
 */
layui.define(['FormField', 'jquery', 'yunj', 'upload'], function (exports) {

    let FormField = layui.FormField;
    let doc = document;
    let $ = layui.jquery;
    let upload = layui.upload;

    class FormFieldImgs extends FormField {

        constructor(options = {}) {
            super(options);
            // 上传操作元素elem
            this.upload_action_elem = `#${this.id} .imgs-upload-box .upload-action-elem`;
            // 图片预览容器dom元素对象
            this.imgs_preview_box_el = null;
            // 上传文件
            this.upload_files = {};
            // 上传进度的数据
            this.upload_progress_data = {};
            // 上传进度的定时器
            this.upload_progress_timer = {};
        }

        defineExtraArgs() {
            let that = this;
            return {
                max: 9,
                size: yunj.config("file.upload_img_size"),
                ext: yunj.config("file.upload_img_ext"),
                text: "图片上传",
                disabled: false
            };
        }

        handleArgs(args) {
            if (args.verify.indexOf("array") === -1)
                args.verify += (args.verify ? "|" : "") + "array";
            return args;
        }

        defineBoxHtml() {
            let that = this;
            return `<div class="layui-form-item yunj-form-item yunj-form-imgs" id="${that.id}">__layout__</div>`;
        }

        layoutControl() {
            let that = this;
            let controlHtml = `<div class="imgs-upload-box">
                                    <i class="upload-action-elem"></i>
                                    <div class="imgs-select-box" title="${that.args.disabled ? '禁用' : '选择图片上传'}">
                                        <i class="layui-icon layui-icon-upload"></i>
                                        <span>${that.args.text}</span>
                                    </div>
                                </div>`;
            return `<div class="layui-input-inline yunj-form-item-control">${controlHtml}</div>`;
        }

        // 设置字段简介
        layoutDesc() {
            let that = this;
            return `<div class="yunj-form-item-desc">允许上传大小不超过 ${that.args.size}MB 且格式为 ${that.args.ext} 的图片，允许最大上传数 ${that.args.max}。${that.args.desc || ""}</div>`;
        }

        // renderDoneSetValue(val) {
        //     let that = this;
        //     $(doc).bind(`yunj_form_${that.formId}_render_done`, function () {
        //         that.setValue(val);
        //     });
        // }

        setValue(val = '') {
            let that = this;
            that.setImgsPreviewBoxLayout(val);
        }

        getValue() {
            let that = this;
            let srcArr = [];
            $(that.imgs_preview_box_el).find('.imgs-preview-item-box img').each(function () {
                let src = $(this).attr('src');
                if (!src || !yunj.isString(src) || src.length > 2000) return true;
                srcArr.push(src);
            });
            return srcArr.length > 0 ? srcArr : "";
        }

        setImgsPreviewBoxLayout(srcArr) {
            let that = this;

            if (yunj.isString(srcArr) && srcArr.length > 0)
                srcArr = yunj.isJson(srcArr) ? JSON.parse(srcArr) : (srcArr.indexOf(",") !== -1 ? srcArr.split(",") : [srcArr]);
            if (!yunj.isArray(srcArr)) srcArr = [];

            if (!that.imgs_preview_box_el) {
                that.fieldBoxEl.find('.imgs-upload-box').append('<div class="imgs-preview-box"></div>');
                that.imgs_preview_box_el = that.fieldBoxEl.find('.imgs-upload-box .imgs-preview-box');
            }

            async function imgsPreviewBoxElContent() {
                let content = '';
                for (let i = 0, l = srcArr.length; i < l; i++) {
                    await ((src) => {
                        return new Promise((resolve, reject) => {
                            yunj.preview_img_style(src, {
                                width: 110,
                                height: 110,
                            }).then(function (style) {
                                let imgItemContent = `<div class="imgs-preview-item-box">
                                            <img src="${src}" alt="" title="点击预览" ${style}>
                                            <i class="layui-icon layui-icon-prev imgs-item-prev-btn" title="${that.args.disabled ? '禁用' : '上移'}"></i>
                                            <i class="layui-icon layui-icon-next imgs-item-next-btn" title="${that.args.disabled ? '禁用' : '下移'}"></i>
                                            <i class="layui-icon layui-icon-delete imgs-item-delete-btn" title="${that.args.disabled ? '禁用' : '删除'}"></i>
                                        </div>`;
                                resolve(imgItemContent);
                            });
                        }).then(function (imgItemContent) {
                            content += imgItemContent;
                        });
                    })(srcArr[i]);
                }
                return content;
            }

            imgsPreviewBoxElContent().then((content) => {
                that.imgs_preview_box_el.html(content);
            });
        }

        async add_imgs_preview_content(imgs = []) {
            let that = this;
            let content = '';
            for (let i = 0, l = imgs.length; i < l; i++) {
                await ((img) => {
                    return new Promise((resolve, reject) => {
                        yunj.preview_img_style(img.src, {
                            width: 110,
                            height: 110,
                        }).then(function (style) {
                            let imgItemContent = `<div class="imgs-preview-item-box" data-index="${img.index}">
                                                    <img src="${img.src}" alt="" title="点击预览" ${style}>
                                                    <i class="layui-icon layui-icon-prev imgs-item-prev-btn" title="${that.args.disabled ? '禁用' : '上移'}"></i>
                                                    <i class="layui-icon layui-icon-next imgs-item-next-btn" title="${that.args.disabled ? '禁用' : '下移'}"></i>
                                                    <i class="layui-icon layui-icon-delete imgs-item-delete-btn" title="${that.args.disabled ? '禁用' : '删除'}"></i>
                                                </div>`;
                            resolve(imgItemContent);
                        });
                    })
                })(imgs[i]).then(function (img_item_content) {
                    content += img_item_content;
                });
            }
            return content;
        }

        // 设置上传进度数据
        set_upload_progress_data(index, args = {}) {
            let defArgs = {
                elem: null,
                rate_num: 0
            };
            args = yunj.objSupp(args, defArgs);
            let that = this;
            if (!that.upload_progress_data.hasOwnProperty(index)) that.upload_progress_data[index] = defArgs;
            that.upload_progress_data[index].elem = that.upload_progress_data[index].elem || that.imgs_preview_box_el.find(`.imgs-preview-item-box[data-index=${index}]`);
            that.upload_progress_data[index].rate_num = args.rate_num;

            if (that.upload_progress_data[index].elem.find('.layui-progress').length <= 0) {
                let progressHtml = `<div class="layui-progress layui-progress-big">
                                      <div class="layui-progress-bar" style="width:0%;">
                                        <span class="layui-progress-text">0%</span>
                                      </div>
                                  </div>`;
                that.upload_progress_data[index].elem.append(progressHtml);
            }

            let percent = args.rate_num + '%';
            that.upload_progress_data[index].elem.find('.layui-progress-bar').css({'width': percent});
            that.upload_progress_data[index].elem.find('.layui-progress-text').html(percent);
        }

        // 上传开始
        upload_progress_start(index) {
            let that = this;

            that.set_upload_progress_data(index, {
                rate_num: 0,
            });
            that.upload_progress_timer[index] = setInterval(function () {
                let rateNum = that.upload_progress_data[index].rate_num;
                rateNum = rateNum + Math.random() * 10 | 0;
                rateNum = rateNum > 99 ? 99 : rateNum;

                that.set_upload_progress_data(index, {
                    rate_num: rateNum,
                });
            }, 300 + Math.random() * 1000);
        }

        // 上传结束
        upload_progress_end(index, data) {
            let that = this;

            clearInterval(that.upload_progress_timer[index]);

            that.set_upload_progress_data(index, {
                rate_num: 100,
            });
            that.upload_progress_data[index].elem.find('img').attr('src', data.url);
            that.upload_progress_data[index].elem.find('img').attr('alt', data.fileName);
            setTimeout(function () {
                that.delete_upload_item_data(index);
            }, 1000);
        }

        // 上传错误
        upload_error(index, tips = '') {
            let that = this;
            if (!that.upload_progress_data.hasOwnProperty(index)) return false;
            if (tips.length <= 0) {
                that.upload_progress_data[index].elem.find('.imgs-upload-item-error-tips').remove();
                return false;
            }
            let html = `<div class="imgs-upload-item-error-tips" title="${tips}">${tips}</div>`;
            that.upload_progress_data[index].elem.append(html);
            that.delete_upload_item_data(index);
        }

        // 删除上传数据
        delete_upload_item_data(index) {
            let that = this;
            if (that.upload_progress_timer.hasOwnProperty(index)) {
                clearInterval(that.upload_progress_timer[index]);
                delete that.upload_progress_timer[index];
            }
            if (that.upload_progress_data.hasOwnProperty(index)) {
                that.upload_progress_data[index].elem.find('.layui-progress').hide();
                delete that.upload_progress_data[index];
            }
        }

        // 设置上传事件绑定
        set_upload_event_bind() {
            let that = this;

            let args = {
                elem: `#${that.id} .imgs-select-box`,
                url: yunj.fileUploadUrl(),
                accept: 'image',
                acceptMime: that.args.ext.split(',').map(item => {
                    return `image/${item}`;
                }).join(','),
                exts: that.args.ext.replace(/,/g, '|'),
                auto: false,
                bindAction: that.upload_action_elem,
                field: 'file',
                size: that.args.size * 1024,
                multiple: true,
                drag: false,
                choose: function (obj) {
                    if (!yunj.isObj(that.upload_files) || !yunj.isEmptyObj(that.upload_files)) {
                        yunj.msg('待上传完成后，执行此操作');
                        return false;
                    }

                    that.upload_files = obj.pushFile();

                    // 判断是否超过限制数量
                    let count = (that.imgs_preview_box_el.find('.imgs-preview-item-box').length | 0) + (Object.keys(that.upload_files).length | 0);
                    if (count > that.args.max) {
                        yunj.msg(`限制最大上传数 ${that.args.max}`);
                        for (let idx in that.upload_files) {
                            if (!that.upload_files.hasOwnProperty(idx)) continue;
                            delete that.upload_files[idx];
                        }
                        return false;
                    }

                    async function setAddImgsPreview() {
                        let imgs = [];
                        for (let index in that.upload_files) {
                            if (!that.upload_files.hasOwnProperty(index)) continue;
                            await new Promise((resolve, reject) => {
                                let file = that.upload_files[index];
                                let reader = new FileReader();
                                reader.readAsDataURL(file);
                                reader.onload = function () {
                                    resolve({
                                        index: index,
                                        src: this.result,
                                    });
                                }
                            }).then(img => {
                                imgs.push(img)
                            });
                        }
                        await that.add_imgs_preview_content(imgs).then(content => {
                            that.imgs_preview_box_el.append(content);
                        });

                        for (let index in that.upload_files) {
                            if (!that.upload_files.hasOwnProperty(index)) continue;
                            that.upload_progress_start(index);
                        }
                        return true;
                    }

                    setAddImgsPreview().then(res => {
                        $(that.upload_action_elem).click();
                    });
                },
                done: function (res, index, upload) {
                    delete that.upload_files[index];
                    if (res.errcode !== 0) {
                        that.upload_error(index, res.msg);
                        return false;
                    }
                    that.upload_progress_end(index, res.data);
                }
            };

            upload.render(args);
        }

        defineExtraEventBind() {
            let that = this;

            if (!that.args.disabled) {
                // 上传
                that.set_upload_event_bind();

                // 删除
                that.fieldBoxEl.on('click', '.imgs-preview-box .imgs-preview-item-box .imgs-item-delete-btn', function (e) {
                    $(this).parent('.imgs-preview-item-box').remove();
                    e.stopPropagation();
                });

                // 上移
                that.fieldBoxEl.on('click', '.imgs-preview-box .imgs-preview-item-box .imgs-item-prev-btn', function (e) {
                    let itemsEl = that.fieldBoxEl.find('.imgs-preview-box .imgs-preview-item-box');
                    let currItem = $(this).parent('.imgs-preview-item-box');
                    let currItemIdx = itemsEl.index(currItem);

                    if (currItemIdx === 0) {
                        currItem.siblings().last().after(currItem);
                    } else {
                        currItem.prev().before(currItem);
                    }
                    e.stopPropagation();
                });

                // 下移
                that.fieldBoxEl.on('click', '.imgs-preview-box .imgs-preview-item-box .imgs-item-next-btn', function (e) {
                    let itemsEl = that.fieldBoxEl.find('.imgs-preview-box .imgs-preview-item-box');
                    let currItem = $(this).parent('.imgs-preview-item-box');
                    let maxItemIdx = itemsEl.length - 1;
                    let currItemIdx = itemsEl.index(currItem);

                    if (currItemIdx === maxItemIdx) {
                        currItem.siblings().first().before(currItem);
                    } else {
                        currItem.next().after(currItem);
                    }
                    e.stopPropagation();
                });
            }

            // 预览
            that.fieldBoxEl.on('click', '.imgs-preview-box .imgs-preview-item-box img', function (e) {
                let src = that.getValue();
                if (src.length <= 0) return false;
                let currSrc = $(this).attr('src');
                let idx = src.indexOf(currSrc);
                if (idx === -1) idx = 0;
                yunj.previewImg(src, idx);
            });
        }

    }

    exports('FormFieldImgs', FormFieldImgs);
});